package main

import (
	"fmt"
	"math"
	"sort"
)

//1、实现对圆形、三角形、长方形求面积。
//2、利用第1题，构造3个以上图形，至少圆形、三角形、矩形各有一个，对上题的图形按照面积降序排列

type areaAll struct {
	a float32
}

type Areaer interface {
	area() float32
}

type Circle struct {
	r float32
	areaAll
}

func (c *Circle) area() float32 {
	c.a = math.Pi * c.r * c.r
	return c.a
}

type Triangle struct {
	d float32
	h float32
	areaAll
}

func (t *Triangle) area() float32 {
	t.a = t.d * t.h / 2
	return t.a
}

type Rectangle struct {
	l float32
	w float32
	areaAll
}

func (r *Rectangle) area() float32 {
	r.a = r.l * r.w
	return r.a
}

func NewCircle(a float32) *Circle {
	m := Circle{r: a}
	return &m
}

func NewTriangle(a, b float32) *Triangle {
	m := Triangle{d: a, h: b}
	return &m
}

func NewRectangle(a, b float32) *Rectangle {
	m := Rectangle{l: a, w: b}
	return &m
}

func GetArea(s Areaer) float32 {
	return s.area()
}

type AreasSlice []Areaer

func (a AreasSlice) Len() int           { return len(a) }
func (a AreasSlice) Swap(i, j int)      { a[i], a[j] = a[j], a[i] }
func (a AreasSlice) Less(i, j int) bool { return a[i].area() < a[j].area() }

// 3、分析斐波那契数列递推公式递归版本的问题，试着为该函数提供一个Cache，使其计算效率提升
var fibCache = make(map[uint]uint, 100)

func fib(n uint) uint {
	if n < 3 {
		fibCache[n] = 1
		return fibCache[n]
	}
	if _, ok := fibCache[n]; !ok {
		fibCache[n] = fib(n-1) + fib(n-2)
	}
	return fibCache[n]
}

// func fib2(n uint) uint {
// 	if n < 3 {
// 		return 1
// 	}
// 	return fib2(n-1) + fib2(n-2)
// }

func main() {
	fmt.Println("==============第一、二题==============")

	c := NewCircle(12.5)
	t := NewTriangle(4.5, 3.6)
	r := NewRectangle(40.2, 30.3)
	g1 := GetArea(c)
	g2 := GetArea(t)
	g3 := GetArea(r)
	fmt.Println(g1, g2, g3)
	areas := make([]Areaer, 0, 10)
	areas = append(areas, c, t, r)
	fmt.Println(areas)
	for _, v := range areas {
		fmt.Printf("%+v\n", v)
	}
	fmt.Println("~~~~~~~~~~~~~~~~~~~~~~~~~~")

	sort.Sort(AreasSlice(areas))
	fmt.Println(areas)
	for _, v := range areas {
		fmt.Printf("%+v\n", v)
	}
	fmt.Println("==============第三题==============")
	fmt.Println(fib(30))
	// fmt.Println("~~~~~~~~~~~~~~~~~~~~~~~~~~")
	// fmt.Println(fib2(30))

}

// 阿飞老师的批改
// 1. 第二题没有看到面积的倒序排序结果，排序这块的逻辑有问题；
// 2. 实际开发工作中，变量名称尽量不要用单个字母，这样很难联系上下文；
